# -*-coding:utf-8-*-
import numpy as np

"""
数据类型对象dtype:
类型          简写
bool	    ?, b1
int8	    b, i1
uint8	    B, u1
int16	    h, i2
uint16	    H, u2
int32	    i, i4
uint32	    I, u4
int64	    q, i8
uint64	    Q, u8
float16	    f2, e
float32	    f4, f
float64	    f8, d
complex64	F4, F
complex128	F8, D
bytes       a,中文字符串需要encode操作
str         S(可以在S后面添加数字,表示字符串长度,比如S3表示长度为三的字符串,不写则为最大长度),不支持中文
unicode     U(可以在后面添加数字表示长度),支持中文
object      O
void        V
"""
dtype1 = np.dtype(np.int32)
dtype2 = np.dtype('i2')
person = np.dtype([('name', 'S10'), ('age', 'i4')])  # 创建结构化数据类型,[('name', '<U'), ('age', '<i4')]

"""
numpy支持数值类型的单个值的创建
"""
num1 = np.int8(12)  # 单个值,print(num1)=12,type(num1)=int8
num2 = np.array(12, dtype='int8')  # 长度为1的0维数组,print(num2)=12,type(num2)=ndarray

"""
N维数组ndarray:
基本的ndarray由numpy.array函数创建
numpy.array参数及描述
1.object: 任何暴露数组接口方法的对象都会返回一个数组或任何(嵌套)序列.
2.dtype: 数组的所需数据类型,可选.
3.copy: 可选,默认为 true ,对象是否被复制.
4.order: C(按行)、F(按列)或A(任意,默认).
5.subok: 默认情况下,返回的数组被强制为基类数组.如果为 true ,则返回子类.
6.ndimin: 指定返回数组的最小维数.
"""
array1 = np.array([[1, 2, 3], [4, 5, 6]])  # [[1 2 3] [4 5 6]]
array2 = np.array(['1', '2', '3'], ndmin=2, dtype=str)  # 最小维度为2,类型为字符串,[['1' '2' '3']]
array3 = np.array([('maqi', 23), ('lisi', 24)], dtype=person)  # 结构化数据类型应用于ndarray,[(b'maqi', 23) (b'lisi', 24)]
names, ages = array3['name'], array3['age']  # [b'maqi' b'lisi'],[23 24]

"""
ndarray属性及方法:
ndarray.T           转置数组
ndarray.flatten     数组的一维副本，flatten函数会请求分配内存来保存结果
ndarray.flat        数组的一维迭代器，返回一个numpy.flatiter对象
ndarray.ravel       数组的一维视图，ravel函数只是返回数组的一个视图（view）
ndarray.shape	    数组维度的元组
ndarray.ndim	    数组维数
ndarray.data	    Python缓冲区对象指向数组的数据的开头
ndarray.size	    数组中的元素数
ndarray.itemsize	一个数组元素的长度，以字节为单位
ndarray.nbytes	    数组元素消耗的总字节数。
ndarray.base	    如果内存来自其他对象，则为基础对象
ndarray.reshape     返回包含具有新形状的相同数据的数组
ndarray.resize      就地更改数组的形状和大小
ndarray.tolist      返回数组对应的列表
ndarray.astype      转换数据类型
ndarray.copy        创建一个深拷贝副本
"""
shape = array1.shape  # 数组形状,(2, 3)
array4 = array1.reshape(3, 2)  # 调整数组形状,返回新的数组,array4=[[1 2] [3 4] [5 6]],array1不变
array1.shape = (3, 2)  # 调整数组自身形状, array1=[[1 2] [3 4] [5 6]]
ndim = array1.ndim  # 数组维度,2
list_ndim_1 = list(array1.ravel())  # 返回数组的一维迭代器, [1, 2, 3, 4, 5, 6]
array1.tolist()  # [[1, 2], [3, 4], [5, 6]]

"""
数组创建例程
"""
# 1.创建指定范围内等间隔的数组
np.arange(2, 10, 2, dtype=int)  # [2 4 6 8], 和range函数的用法一致
# 2.创建指定范围内指定个数的等间隔数组.endpoint:生成的数组是否包含stop值,默认为ture
np.linspace(1, 10, 4, endpoint=False)  # [1. 3.25 5.5 7.75]. endpoint为True时结果为[1. 4. 7. 10.]
# 3.创建指定形状和dtype的未初始化数组
np.empty((2, 2), dtype=int)  # 数组元素为随机值，因为它们未初始化
np.empty((2, 2), dtype=int).fill(8)  # 初始化指定值
# 4.创建指定形状,以0填充的数组
np.zeros((2, 3), dtype=float)  # [[0. 0. 0.] [0. 0. 0.]]
# 5.创建指定形状,以1填充的数组
np.ones((2, 3), dtype=int)  # [[1 1 1] [1 1 1]]
# 6.创建来自现有数据的数组
np.asarray([(1, 2), (4, 5)], dtype=int)  # [[1 2] [4 5]],此函数类似于numpy.array,除了它有较少的参数
# 7.创建来自可迭代对象的数组
np.fromiter((i for i in range(5)), dtype=int)  # [0 1 2 3 4]
# 8.通过random模块创建随机数组
np.random.random((2, 3))  # 指定形状的数组, 参数为int(一维数组)或元组, 随机样本位于[0.0, 1.0)
np.random.rand(2, 3)  # 指定形状的数组, 随机样本位于[0.0, 1.0)
np.random.randn(2, 3)  # 指定形状,随机样本位于[0.0, 1.0),与rand的区别是具有标准正态分布的数组
np.random.randint(0, 10, size=(2, 3))  # 返回[low, high)之间的随机整数,low和high只有一个参数时为high,参数size为int或元组
# np.random.choice从给定的一维数组中生成随机样本，参数一为int或1-D array-like,参数size为int或元组.
np.random.choice(5, size=(2, 3))  # 效果等同于np.random.randint(0,5,3)
np.random.choice([1, 4, 5], size=5, p=[0.5, 0.3, 0.2])  # 从参数一的元素中生成数组, 参数p为参数一的每个元素选取概率
a = np.random.choice(5, size=3, replace=False)  # replace指定数组元素能否重复,默认True(数组元素个数小于参数一元素个数才能为False)
# 9.对数组元素进行打乱顺序,注意多维数组只是打乱第一维的顺序
np.random.shuffle(array1)  # array1:[[3 4] [5 6] [1 2]]
# 10.创建指定形状和指定值(类型可以广播成指定形状就行)的数组
np.full((2, 3), 9)  # [[9 9 9] [9 9 9]],指定每个元素的值
np.full((2, 3), [1, 2, 3])  # [[1 2 3] [1 2 3]],指定每行值
np.full((2, 3), [[1], [2]])  # [[1 1 1] [2 2 2]],指定每列值
# 11.创建和给定数组形状相同的数组
np.full_like(array1, 9)
np.ones_like(array1)
np.zeros_like(array1)
np.empty_like(array1)

